﻿// -------------------------------------------------------------------------------------------------------------------------------
// <copyright file="TestAddFactorMatrix.cs" company="Exul">
//     Copyright (c) Exul. All rights reserved.
// </copyright>
// <author>
//     Exul
// </author>
// -------------------------------------------------------------------------------------------------------------------------------

namespace ExulLibrary.Mathematics.LinearAlgebra.Sequential.Tests.MatrixExtensionsTest.DoubleExtensions
{
    #region Usings

    using ExulLibrary.Mathematics.LinearAlgebra.Sequential.DoubleExtensions;

    using NUnit.Framework;

    #endregion

    /// <summary>
    ///     Test suite for <see cref="MatrixExtensions.Add(Matrix{double},double,Matrix{double})"/>.
    /// </summary>
    [TestFixture]
    [Category("ExulLibrary.Mathematics.LinearAlgebra.Sequential.DoubleExtensions.MatrixExtensions")]
    public sealed class TestAddFactorMatrix
    {
        #region Methods

        #region public

        /// <summary>
        ///     Tests the method when matrix has <see cref="RMDenseMatrix{T}"/> type.
        /// </summary>
        [Test]
        public void WhenAugendAndAddendHaveTheSameSize()
        {
            // Arrange
            var augendData = new[]
                             {
                                 new double[] { 1, 2, 3 },
                                 new double[] { 4, 5, 6 }
                             };
            var augend = new RMDenseMatrix<double>(augendData);
            var addendData = new[]
                             {
                                 new double[] { 10, 15, 20 },
                                 new double[] { 25, 30, 35 }
                             };
            var addend = new RMDenseMatrix<double>(addendData);
            var expectedResult = new[]
                                 {
                                     new double[] { 20, 35, 50 },
                                     new double[] { 65, 80, 95 }
                                 };

            // Act
           MatrixExtensions.Add(augend, 10, addend);

            // Assert
            Assert.That(augend.Values, Is.EquivalentTo(expectedResult));
        }

        /// <summary>
        ///     Tests the method when matrix has <see cref="CMDenseMatrix{T}"/> type.
        /// </summary>
        [Test]
        public void WhenMatrixHasCMDenseMatrixType()
        {
            // Arrange
            var augendData = new[]
                             {
                                 new double[] { 1, 2 },
                                 new double[] { 3, 4 },
                                 new double[] { 5, 6 }
                             };
            var augend = new CMDenseMatrix<double>(augendData);
            var addendData = new[]
                             {
                                 new double[] { 10, 15 },
                                 new double[] { 20, 25 },
                                 new double[] { 30, 35 }
                             };
            var addend = new CMDenseMatrix<double>(addendData);
            var expected = new[]
                           {
                               new double[] { 20, 35 },
                               new double[] { 50, 65 },
                               new double[] { 80, 95 }
                           };

            // Act
            MatrixExtensions.Add(augend, 10, addend);

            // Assert
            Assert.That(augend.Values, Is.EquivalentTo(expected));
        }

        /// <summary>
        ///     Tests the method when matrix has <see cref="CMFlattenDenseMatrix{T}"/> type.
        /// </summary>
        [Test]
        public void WhenMatrixHasCMFlattenDenseMatrixType()
        {
            // Arrange
            var augendData = new double[]
                             {
                                 1, 2,
                                 3, 4,
                                 5, 6
                             };
            var augend = new CMFlattenDenseMatrix<double>(2, 3, augendData);
            var addendData = new double[]
                             {
                                 10, 15,
                                 20, 25,
                                 30, 35
                             };
            var addend = new CMFlattenDenseMatrix<double>(2, 3, addendData);
            var expected = new[]
                           {
                               20, 35,
                               50, 65,
                               80, 95
                           };

            // Act
            MatrixExtensions.Add(augend, 10, addend);

            // Assert
            Assert.That(augend.Values, Is.EquivalentTo(expected));
        }

        /// <summary>
        ///     Tests the method when matrix has <see cref="DenseSymmetricMatrix{T}"/> type.
        /// </summary>
        [Test]
        public void WhenMatrixHasDenseSymmetricMatrixType()
        {
            // Arrange
            var addendData = new double[]
                             {
                                 1,
                                 2, 3
                             };
            var addend = new DenseSymmetricMatrix<double>(addendData);
            var augendData = new double[]
                             {
                                 10,
                                 20, 30
                             };
            var augend = new DenseSymmetricMatrix<double>(augendData);
            var expectedResult = new double[]
                                 {
                                     21,
                                     42, 63
                                 };

            // Act
            MatrixExtensions.Add(augend, 2, addend);

            // Assert
            Assert.That(augend.Values, Is.EquivalentTo(expectedResult));
        }

        /// <summary>
        ///     Tests the method when matrix has <see cref="RMFlattenDenseMatrix{T}"/> type.
        /// </summary>
        [Test]
        public void WhenMatrixHasRMFlattenDenseMatrix()
        {
            // Arrange
            var augendData = new double[]
                             {
                                 1, 2, 3,
                                 4, 5, 6
                             };
            var augend = new RMFlattenDenseMatrix<double>(2, 3, augendData);
            var addendData = new double[]
                             {
                                 10, 15, 20,
                                 25, 30, 35
                             };
            var addend = new RMFlattenDenseMatrix<double>(2, 3, addendData);
            var expected = new[]
                           {
                               20, 35, 50,
                               65, 80, 95
                           };

            // Act
            MatrixExtensions.Add(augend, 10, addend);

            // Assert
            Assert.That(augend.Values, Is.EquivalentTo(expected));
        }

        #endregion

        #endregion
    }
}